﻿<%
Class DbClass
	'数据库类型,当前数据库连接对象,ADO获取记录集的方式
	Private s_dbType, s_conn, s_queryType
	'使用分页相关
	'当前分页存储过程名称,当前分页记录集总页数,当前分页记录集总记录数,当前页码
	Private s_pageSpName, s_pageCount, s_pageRecordCount, s_pageIndex
	
	'''构造
	Private Sub Class_Initialize()
		'Easp.Error(11) = "无效的查询条件，无法获取记录集！"
		'Easp.Error(12) = "数据库服务器端连接错误，请检查数据库连接信息是否正确！"
		'Easp.Error(13) = "无效的数据库连接！"
		'Easp.Error(14) = "无效的查询条件，无法获取新的ID号！"
		'Easp.Error(15) = "生成Json格式代码出错！"
		'Easp.Error(16) = "生成不重复的随机字符串出错！"
		'Easp.Error(17) = "生成不重复的随机数出错！"
		'Easp.Error(18) = "获取随机记录失败，请输入要取的记录数量！"
		'Easp.Error(19) = "获取随机记录失败，请在表名后输入:ID字段的名称！"
		'Easp.Error(20) = "向数据库添加记录出错！"
		'Easp.Error(21) = "更新数据库记录出错！"
		'Easp.Error(22) = "从数据库删除数据出错！"
		'Easp.Error(23) = "从数据库获取数据出错！"
		'Easp.Error(32) = "仅支持从MS SQL Server数据库调用存储过程！"
		'Easp.Error(24) = "调用存储过程出错！"
		'Easp.Error(25) = "执行SQL语句出错！"
		'Easp.Error(26) = "生成SQL语句出错！"
		'Easp.Error(27) = "获取分页数据出错，数组必须是4个元素（必须提供数据库表的主键）！"
		'Easp.Error(28) = "获取分页数据出错，使用数组条件获取分页数据时条件参数必须为数组！"
		'Easp.Error(29) = "获取分页数据出错，使用自带分页存储过程时条件数组参数必须为6个元素！"
		'Easp.Error(30) = "获取分页数据出错，使用自定义分页存储过程时必须包含@@RecordCount和@@PageCount输出参数！"
		'Easp.Error(31) = "获取分页数据出错，使用存储过程获取分页数据时条件参数必须为数组！"
		s_dbType = ""
		s_queryType = 0
		s_pageSpName   = "sp_ashapo_pager"
		s_pageIndex = Null
		'设置是否自动连接
	End Sub
	
	'''析构
	Private Sub Class_Terminate()
		If TypeName(s_conn) = "Connection" Then
			If s_conn.State = 1 Then s_conn.Close
			Set s_conn = Nothing
		End If
		Set o_pageDic = Nothing
	End Sub
	
	'''根据conn对象获取数据库类型ACCESS/MSSQL/MYSQL/ORACLE
	'p_c:conn对象
	Private Function getDataType_(Byval p_c)
		Dim t_s,t_i : t_s = UCase(p_c.Provider)
		Dim t_ms, t_ac, t_my, t_oc
		t_ms = Split("SQLNCLI10, SQLXMLOLEDB, SQLNCLI, SQLOLEDB, MSDASQL",", ")
		t_ac = Split("MICROSOFT.ACE.OLEDB.12.0, MICROSOFT.JET.OLEDB.4.0",", ")
		t_my = "MYSQLPROV"
		t_oc = Split("MSDAORA, OLEDB.ORACLE",", ")
		For t_i = 0 To Ubound(t_ms)
			If Instr(t_s,t_ms(t_i))>0 Then
				getDataType_ = "MSSQL" : Exit Function
			End If
		Next
		For t_i = 0 To Ubound(t_ac)
			If Instr(t_s,t_ac(t_i))>0 Then
				getDataType_ = "ACCESS" : Exit Function
			End If
		Next
		If Instr(t_s,t_my)>0 Then
			getDataType_ = "MYSQL" : Exit Function
		End If
		For t_i = 0 To Ubound(t_oc)
			If Instr(t_s,t_oc(t_i))>0 Then
				getDataType_ = "ORACLE" : Exit Function
			End If
		Next
	End Function
	
	'''设置Conn对象
	'p_c:conn对象
	Public Property Let Conn(Byval p_c)
		If TypeName(p_c) = "Connection" Then
			Set s_conn = p_c
			s_dbType = getDataType_(p_c)
		Else
			'出错处理
			'Asp.Go500()
		End If
	End Property
	
	'''获取Conn
	Public Property Get Conn()
		If TypeName(s_conn) = "Connection" Then
			Set Conn = s_conn
		End If
	End Property
	
	'''获取数据库类型
	Public Property Get DatabaseType()
		DatabaseType = s_dbType
	End Property
	
	'''设置用ADO获取记录集的方式，此属性为只写
	'p_s:属性值为1或"command"时，ADO用ADODB.Command方式获取记录集,其余情况ADO用ADODB.RecordSet方式获取记录集，默认为0
	Public Property Let QueryType(Byval p_s)
		p_s = Lcase(p_s)
		If p_s = "1" or p_s = "command" Then
			s_queryType = 1
		Else
			s_queryType = 0
		End If
	End Property
	
	'''设置默认分页存储过程名称
	'p_s:分页存储过程名称字符串
	Public Property Let PageSpName(Byval p_s)
		s_pageSpName = p_s
	End Property
	
	'''实例化一个DbClass,用于开启多个数据库连接
	Public Function [New]()
		Set [New] = New DbClass
	End Function

	'''关闭数据连接或记录集对象并资源释放资源
	'p_o:对象名
	Public Function C(ByRef p_o)
		On Error Resume Next
		p_o.Close()
		Set p_o = Nothing
	End Function
	
	'''根据自定义连接字符串建立数据库连接对象
	'p_s:连接字符
	Public Function CreatConn(Byval p_s)
		On Error Resume Next
		Dim t_c : Set t_c = Server.CreateObject("ADODB.Connection")
		t_c.Open p_s
		If Err.number <> 0 Then
			t_c.Close
			Set t_c = Nothing
			'出错处理
			'asp.Go500()
		End If
		Set CreatConn = t_c
	End Function
	
	'''根据模板建立数据库连接对象
	'支持MSSQL、ACCESS、MYSQL、ORACLE
	'如要连接其他类型数据库可用 CreatConn 方法用自定义字符串建立连接对象
	'p_t:数据库类型
	'p_d:数据库名/Access路径
	'p_s:accessPass|user[:password]@server[:port]
	Public Function OpenConn(Byval p_t, Byval p_d, Byval p_s)
		Dim t_t, t_s, t_u, t_p, t_o
		t_s = "" : t_u = "" : t_p = "" : t_o = ""
		If Instr(p_s,"@")>0 Then
			t_s = Trim(Mid(p_s,InstrRev(p_s,"@")+1))
			t_u = Trim(Left(p_s,InstrRev(p_s,"@")-1))
			If Instr(t_s,":")>0 Then
				t_o = Trim(Mid(t_s,Instr(t_s,":")+1))
				t_s = Trim(Left(t_s,Instr(t_s,":")-1))
			End If
			If Instr(t_u,":")>0 Then
				t_p = Trim(Mid(t_u,Instr(t_u,":")+1))
				t_u = Trim(Left(t_u,Instr(t_u,":")-1))
			End If
		Else
			If Instr(p_s,":")>0 Then
				t_u = Trim(Left(p_s,Instr(p_s,":")-1))
				t_p = Trim(Mid(p_s,Instr(p_s,":")+1))
			Else
				t_p = Trim(p_s)
			End If
		End If
		s_dbType = UCase(Cstr(p_t))
		Select Case s_dbType
			Case "0","MSSQL"
				If t_o = "" Then
					t_t = "Provider=sqloledb;Data Source=" & t_s & ";Initial Catalog=" & p_d & ";User Id=" & t_u & ";Password=" & t_p & ";"
				Else
					t_t = "Provider=sqloledb;Data Source=" & t_s & "," & t_o & ";Initial Catalog=" & p_d & ";User Id=" & t_u & ";Password=" & t_p & ";"
				End If
			Case "1","ACCESS"
				Dim t_d
				If Instr(p_d,":")>0 Then
					t_d = p_d
				Else
					t_d = Server.MapPath(p_d)
				End If
				t_t = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & t_d & ";Jet OLEDB:Database Password=" & t_p & ";"
			Case "2","MYSQL"
				If t_o = "" Then t_o = "3306"
				t_t = "Driver={mySQL};Server=" & t_s & ";Port=" & t_o & ";Option=131072;Stmt=;Database=" & p_d & ";Uid=" & t_u & ";Pwd=" & t_p & ";"
			Case "3","ORACLE"
				t_t = "Provider=msdaora;Data Source=" & t_s & ";User Id=" & t_u & ";Password=" & t_p & ";"
		End Select
		Set OpenConn = CreatConn(t_t)
	End Function

	'''根据SQL语句获取记录集
	'p_s:SQL语句
	Public Function GetRecordBySQL(Byval p_s)
		'On Error Resume Next
		If s_queryType = 1 Then
			Dim t_c : Set t_c = Server.CreateObject("ADODB.Command")
			With t_c
				.ActiveConnection = s_conn
				.CommandText = p_s
				Set GetRecordBySQL = .Execute
			End With
			Set t_c = Nothing
		Else
			Dim t_r : Set t_r = Server.CreateObject("Adodb.Recordset")
			With t_r
				.ActiveConnection = s_conn
				.CursorType = 1
				.LockType = 1
				.Source = p_s
				.Open
			End With
			Set GetRecordBySQL = t_r
		End If
		Sa.DbQueryTimes = Sa.DbQueryTimes + 1
		If Err.number <> 0 Then
			'错误处理
			'Asp.Go500()
			'Easp.Error.Msg = "<br />" & s
			'Easp.Error.Raise 11
			Err.Clear
		End If
	End Function
	
	'''根据SQL语句获取记录集
	'GetRecordBySql的别名
	Public Function GRS(Byval p_s)
		Set GRS = GetRecordBySQL(p_s)
	End Function

	'''数组参数格式组装所需语句
	'p_t:表名
	'p_v:数组
	'p_p:返回类型，1:And语句/2:字段名返回/3:数值返回/其它:字段数值对返回
	Private Function valueToSql_(Byval p_t, Byval p_v, Byval p_p)
		On Error Resume Next
		Dim t_s : t_s = p_v
		If IsArray(p_v) Then
			t_s = ""
			Dim t_r, t_f, t_v, t_i
			Set t_r = GRS("Select Top 1 * From [" & p_t & "] Where 1 = -1")
			For t_i = 0 to Ubound(p_v)
				t_f = Param(p_v(t_i))(0)
				t_v = Param(p_v(t_i))(1)
				t_v = Replace(t_v,"'","''")
				If t_i <> 0 Then
					t_s = t_s & IIF(p_p=1, " And ", ", ")
				End If
				If p_p = 2 Then
					t_s = t_s & "[" & t_f & "]"
				Else
					Select Case t_r.Fields(t_f).Type
						Case 8,129,130,133,134,200,201,202,203
							t_s = t_s & IIF(p_p = 3, "'" & t_v & "'", "[" & t_f & "] = '" & t_v & "'")
						Case 7,135
							t_v = IIF(IsN(t_v),"NULL","'" & t_v & "'")
							t_s = t_s & IIF(p_p = 3, t_v, "[" & t_f & "] = " & t_v)
						Case 11
							Dim t_tf, t_tv : t_tv = UCase(Cstr(Trim(t_v)))
							t_tf = IIF(t_tv="TRUE" Or t_tv = "1", IIF(s_dbType="ACCESS","True","1"), IIF(s_dbType="ACCESS", IIF(t_tv="","NULL","False"), IIF(t_tv="","NULL","0")))
							t_s = t_s & IIF(p_p = 3, t_tf, "[" & t_f & "] = " & t_tf)
						Case Else
							t_v = IIF(IsN(t_v),"NULL",t_v)
							t_s = t_s & IIF(p_p = 3, t_v, "[" & t_f & "] = " & t_v)
					End Select
				End If
			Next
			t_r.Close() : Set t_r = Nothing 
			If Err.number <> 0 Then
				'错误处理
				'Asp.Go500()
				'Easp.Error.Raise 26 : Err.Clear
			End If
		End If
		valueToSql_ = t_s
	End Function
	
	'''生成取得符合条件的纪录集的SQL语句
	'调用此方法将返回一个由指定条件生成的SQL查询语句
	'p_t:表名
	'p_c:条件(条件数组/条件字符串)
	'p_o:排序字段
	Public Function SqlforGetRecord(Byval p_t,Byval p_c,Byval p_o)
		Dim t_s, t_f, t_n, t_o, t_p, t_t
		t_f = "" : t_n = 0
		t_o = Param(p_t)
		If Has(t_o(1)) Then
			t_t = Trim(t_o(0)) : t_f = Trim(t_o(1)) : t_o = ""
			t_p = Param(t_f)
			If Has(t_p(1)) Then
				t_f = Trim(t_p(0)) : t_n = Int(Trim(t_p(1))) : t_p = ""
			Else
				If isNumeric(t_f) Then
					t_n = Int(t_f) : t_f = ""
				End If
			End If
		Else
			t_t = t_o(0)
		End If
		t_s = "Select "
		If t_n > 0 Then
			t_s = t_s & "Top " & t_n & " "
		End If
		t_s = t_s & IIF(t_f <> "", t_f, "* ")
		t_s = t_s & " From [" & t_t & "]"
		If IsArray(p_c) Then
			t_s = t_s & " Where " & valueToSql_(t_t,p_c,1)
		Else
			If p_c <> "" Then
				t_s = t_s & " Where " & p_c
			End If
		End If
		If p_o <> "" Then
			t_s = t_s & " Order By " & p_o
		End If
		SqlforGetRecord = t_s
	End Function
	
	'''生成取得符合条件的纪录集的SQL语句
	'SqlforGetRecord的别名
	Public Function SGR(Byval p_t,Byval p_c,Byval p_o)
		SGR = SqlforGetRecord(p_t, p_c, p_o)
	End Function
	
	'''取得符合条件的纪录集
	'p_t:表名
	'p_c:条件(条件数组/条件字符串)
	'p_o:排序字段
	Public Function GetRecord(Byval p_t,Byval p_c,Byval p_o)
		Set GetRecord = GRS(SqlforGetRecord(p_t, p_c, p_o))
	End Function
	
	'''取得符合条件的纪录集
	'GetRecord的别名
	Public Function GR(Byval p_t,Byval p_c,Byval p_o)
		Set GR = GetRecord(p_t, p_c, p_o)
	End Function
	
	'''根据某一条件获取指定纪录的详细数据
	'调用此方法将根据查询条件返回一个最多包含一条符合查询条件记录的记录集对象
	'p_t:表名
	'p_c:条件(条件数组/条件字符串)
	Public Function GetRecordDetail(Byval p_t, Byval p_c)
		Dim t_s : t_s = "Select Top 1 * From [" & p_t & "] Where " & valueToSql_(p_t, p_c, 1)
		Set GetRecordDetail = GRS(t_s)
	End Function
	
	'''根据某一条件获取指定纪录的详细数据
	'GetRecordDetail的别名
	'p_t:表名
	'p_c:条件(条件数组/条件字符串)
	Public Function GRD(Byval p_t, Byval p_c)
		Set GRD = GetRecordDetail(p_t, p_c)
	End Function

	'''获取一个指定数量的随机数据记录集
	'p_t:数据表名称:字段:数量
	'p_c:数组条件/字符串条件
	Public Function GetRandRecord(Byval p_t, Byval p_c)
		Dim t_s, t_o, t_p, t_f, t_i, t_n
		t_o = Param(p_t)
		If Has(t_o(1)) Then
			p_t = t_o(0)
			t_p = Param(t_o(1))
			If IsN(t_p(1)) Then
				'出错处理
				'Asp.Go500()
				'Easp.Error.Raise 18
				Exit Function
			Else
				t_f = t_p(0) : t_n = t_p(1)
				If Instr(t_f,",")>0 Then
					t_i = Trim(Left(t_f,Instr(t_f,",")-1))
				Else
					t_i = t_f : t_f = "*"
				End If
			End If
		Else
			'出错处理
			'Asp.Go500()
			'Easp.Error.Raise 19
			Exit Function
		End If
		p_c = IIF(IsN(p_c),""," Where " & valueToSql_(p_t, p_c, 1))
		t_s = "Select Top " & t_n & " " & t_f & " From ["&p_t&"]" & p_c
		Select Case s_dbType
		Case "ACCESS"
			Randomize(Timer())
			t_s = t_s & " Order By Rnd(-(" & t_i & "+" & Rnd() & "))"
		Case "MSSQL"
			t_s = t_s & " Order By newid()"
		Case "MYSQL"
			t_s = "Select " & t_f & " From " & p_t & p_c & " Order By rand() limit " & t_n
		Case "ORACLE"
			t_s = "Select " & t_f & " From (Select " & t_f & " From " & p_t & " Order By dbms_random.value) " & IIF(IsN(p_c), "Where", p_c & " And") & " rownum < " & Int(t_n)+1
		End Select
		Set GetRandRecord = GRS(t_s)
	End Function
	
	'''获取一个指定数量的随机数据记录集
	'GetRandRecord的别名
	Public Function GRR(Byval p_t, Byval p_c)
		Set GRR = GetRandRecord(p_t, p_c)
	End Function
	
	'''自动获取新的(数据库没有的)唯一序列号（自动编号）
	'如有可能请尽量提供ID字段的名称，这样将大大提高生成新编号的效率。
	'p_t:数据表名称[:ID字段名称]
	Public Function AutoID(Byval p_t)
		On Error Resume Next
		Dim t_r, t_t, t_f, t_i, t_n : t_f = "" : t_i = 0
		t_t = Param(p_t)
		If Has(t_t(1)) Then
			t_n = t_t(0) : t_f = t_t(1) : t_t = ""
		End If
		Set t_r = GRS("Select " & IIF(t_f<>"", "Max(" & t_f & ")", "Top 1 *") & " From [" & t_n & "]")
		If t_r.eof Then
			AutoID = 1 : Exit Function
		Else
			If t_f<>"" Then
				If IsN(t_r.Fields.Item(0).Value) Then
					AutoID = 1 : Exit Function
				End If
				AutoID = t_r.Fields.Item(0).Value + 1
				Exit Function
			Else
				Dim t_w
				Set t_w = GRS("Select Max(" & t_r.Fields.Item(0).Name & ") From [" & t_n & "]")
				t_i = t_w.Fields.Item(0).Value + 1
				t_w.Close()
				Set t_w = Nothing
			End If
		End If
		t_r.Close()
		Set t_r = Nothing
		If Err.number <> 0 Then
			'出错处理
			'Asp.Go500()
			'Easp.Error.Raise 14
		End If
		AutoID = t_i
	End Function
	
	'''生成一个不重复的指定长度的随机字符串
	'p_l:长度[:范围] | 最小值-最大值 | 嵌入的字符串[:长度或范围]
	'p_f:表名:字段名
	Public Function RandStr(Byval p_l, Byval p_f)
		On Error Resume Next
		Dim t_t, t_f, t_s, t_r
		t_t = Param(p_f)(0)
		t_f = Param(p_f)(1)
		t_s = RandStr_s(p_l)	'这里应该会出问题
		Do While (True)
			Set t_r = GR(t_t & ":" & t_f & ":1", t_f & "='" & t_s & "'", "")
			If Not t_r.Bof And Not t_r.Eof Then
				t_s = RandStr_s(p_l)
			Else
				RandStr = t_s
				Exit Do
			End If
			C(t_r)
		Loop
		If Err.number <> 0 Then
			'出错处理
			'Asp.Go500()
			'Easp.Error.Raise 16
		End If
	End Function
	
	'''生成一个不重复的随机数
	'p_s:最小值
	'p_b:最大值
	'p_f:表名:字段名
	Public Function Rand(Byval p_s, Byval p_b, Byval p_f)
		On Error Resume Next
		Dim t_t, t_f, t_s, t_r
		t_t = Param(p_f)(0)
		t_f = Param(p_f)(1)
		t_s = Rand_s(p_s, p_b)
		Do While (True)
			Set t_r = GR(t_t & ":" & t_f & ":1", Array(t_f & ":" & t_s),"")
			If Not t_r.Bof And Not t_r.Eof Then
				t_s = Rand_s(p_s, p_b)
			Else
				Rand = t_s
				Exit Do
			End If
			C(t_r)
		Loop
		If Err.number <> 0 Then
			'出错处理
			'Asp.Go500()
			'Easp.Error.Raise 17
		End If
	End Function
	
	'''底层执行sql动作语句
	'p_s:sql动作语句
	Private Function doExecute_(Byval p_s)
		Dim t_e : Set t_e = Server.CreateObject("ADODB.Command")
		With t_e
			.ActiveConnection = s_conn
			.CommandText = p_s
			doExecute_ = .Execute
		End With
		Set t_e = Nothing
	End Function
	
	'''执行指定的SQL语句
	'如果是获取记录集操作，执行成功返回记录集对象，执行失败返回ERR
	'如果是执行SQL语句，执行成功返回1，执行失败返回0
	'p_s:sql语句
	Public Function Exec(Byval p_s)
		On Error Resume Next
		If Lcase(Left(Trim(p_s),6)) = "select" Then
			Dim t_i : t_i = s_queryType
			s_queryType = 1
			Set Exec = GRS(p_s)
			s_queryType = t_i
			If Err.number <> 0 Then
				'出错处理
				'Easp.Error.Msg = "<br />" & s
				'Easp.Error.Raise 25
				'Err.Clear
			End If
		Else
			Exec = 1 : doExecute_(p_s)
			If Err.number <> 0 Then
				Exec = 0
			End If
		End If
	End Function

	'''生成添加一个新的纪录的SQL语句
	'p_t:表名[:ID字段名]
	'p_v:要插入表的字段和值
	Public Function SqlforAddRecord(Byval p_t, Byval p_v)
		Dim t_s, t_f, t_v, t_o
		t_o = Param(p_t)
		If Has(t_o(1)) Then
			p_t = t_o(0)
		End If
		t_f = valueToSql_(p_t, p_v, 2)
		t_v = valueToSql_(p_t, p_v, 3)
		t_s = "Insert Into [" & p_t & "] (" & t_f & ") Values (" & t_v & ")"
		SqlforAddRecord = t_s
	End Function
	
	'''生成添加一个新的纪录的SQL语句
	'SqlforAddRecord的别名
	Public Function SAR(Byval p_t, Byval p_v)
		SAR = SqlforAddRecord(p_t, p_v)
	End Function
	
	'''添加一条新的纪录,成功返回1(带id则返回新添加的id),失败返回0
	'要插入表的字段和值，只能是数组且应遵循"数组参数约定" 
	'p_t:表名[:ID字段名]
	'p_v:要插入表的字段和值
	Public Function AddRecord(Byval p_t,Byval p_v)
		On Error Resume Next
		Dim t_o, t_s : t_o = Param(p_t)
		If Has(t_o(1)) Then p_t = t_o(0)
		t_s = SqlforAddRecord(p_t, p_v)
		doExecute_(t_s)
		If Err.number <> 0 Then
			'出错处理
			'Easp.Error.Msg = "<br />" & s
			'Easp.Error.Raise 20
			Err.Clear()
			AddRecord = 0
			Exit Function
		End If
		If Has(t_o(1)) Then
			AddRecord = AutoID(t_o(0) & ":" & t_o(1))-1
		Else
			AddRecord = 1
		End If
		Err.Clear()
	End Function
	
	'''添加一条新的纪录
	'AddRecord的别名
	Public Function AR(Byval p_t, Byval p_v)
		AR = AddRecord(p_t, p_v)
	End Function
	
	'''生成根据指定条件更新纪录的SQL语句
	'p_t:表名
	'p_c:条件(条件数组/条件字符串)
	'p_v:更新的字段及值对
	Public Function SqlforUpdateRecord(Byval p_t, Byval p_c, Byval p_v)
		Dim t_s
		t_s = "Update [" & p_t & "] Set "
		t_s = t_s & valueToSql_(p_t, p_v, 0)
		If Has(p_c) Then
			t_s = t_s & " Where " & valueToSql_(p_t, p_c, 1)
		End If
		SqlforUpdateRecord = t_s
	End Function
	
	'''生成根据指定条件更新纪录的SQL语句
	'SqlforUpdateRecord的别名
	Public Function SUR(Byval p_t, Byval p_c, Byval p_v)
		SUR = SqlforUpdateRecord(p_t, p_c, p_v)
	End Function
	
	'''根据指定条件更新记录
	'p_t:表名
	'p_c:条件(条件数组/条件字符串)
	'p_v:更新的字段及值对
	Public Function UpdateRecord(Byval p_t, Byval p_c, Byval p_v)
		On Error Resume Next
		Dim t_s : t_s = SqlforUpdateRecord(p_t, p_c, p_v)
		doExecute_(t_s)
		If Err.number <> 0 Then
			'错误处理
			'Easp.Error.Msg = "<br />" & s
			'Easp.Error.Raise 21
			UpdateRecord = 0
			Exit Function
		End If
		UpdateRecord = 1
		Err.Clear()
	End Function
	
	'''根据指定条件更新记录
	'UpdateRecord的别名
	Public Function UR(Byval p_t, Byval p_c, Byval p_v)
		UR = UpdateRecord(p_t, p_c, p_v)
	End Function
	
	'''生成删除符合条件的纪录的SQL语句
	'p_t:表名
	'p_c:条件(条件数组/条件字符串/由逗号隔开的多个值)
	Public Function SqlforDeleteRecord(Byval p_t, Byval p_c)
		Dim t_i, t_v, t_s, t_p : t_i = "" : t_v = ""
		If Not IsArray(p_c) Then
			t_p = Param(p_c)
			If Has(t_p(1)) Then
				t_i = t_p(0)
				If Instr(t_i," ")=0 Then
					t_v = t_p(1)
				Else
					t_i = ""
				End If
			End If
		End If
		t_s = "Delete From [" & p_t & "] Where " & IIF(t_i="", valueToSql_(p_t, p_c, 1), "[" & t_i & "] In (" & t_v & ")")
		SqlforDeleteRecord = t_s
	End Function
	
	'''生成删除符合条件的纪录的SQL语句
	'SqlforDeleteRecord的别名
	Public Function SDR(Byval p_t,Byval p_c)
		SDR = SqlforDeleteRecord(p_t, p_c)
	End Function
	
	'''根据指定条件删除记录,成功返回1,失败返回0
	'p_t:表名
	'p_c:条件(条件数组/条件字符串/由逗号隔开的多个值)
	Public Function DeleteRecord(Byval p_t,Byval p_c)
		On Error Resume Next
		Dim t_s : t_s = SqlforDeleteRecord(p_t, p_c)
		doExecute_(t_s)
		If Err.number <> 0 Then
			'出错处理
			'Easp.Error.Msg = "<br />" & s
			'Easp.Error.Raise 22
			DeleteRecord = 0
			Exit Function
		End If
		DeleteRecord = 1
		Err.Clear()
	End Function
	
	'''根据指定条件删除记录
	'DeleteRecord的别名
	Public Function DR(Byval p_t, Byval p_c)
		DR = DeleteRecord(p_t, p_c)
	End Function
	
	'''根据指定条件获取某条纪录中的其他字段的内容
	'p_t:表名
	'p_c:条件(条件数组/条件字符串)
	'p_g:单个字段名或者由逗号隔开的多个字段名
	Public Function ReadTable(Byval p_t, Byval p_c, Byval p_g)
		On Error Resume Next
		Dim t_r, t_s, t_a, t_as, t_ts, t_i
		t_ts = "" : t_as = ""
		t_s = "Select " & p_g & " From [" & p_t & "] Where " & valueToSql_(p_t, p_c, 1)
		Set t_r = GRS(t_s)
		If Not t_r.Eof Then
			If Instr(p_g,",") > 0 Then
				t_a = Split(p_g,",")
				For t_i = 0 To Ubound(t_a)
					If t_i<>0 Then
						t_as = t_as & Chr(0)
					End If
					t_as = t_as & t_r.Fields.Item(t_i).Value
				Next
				t_ts = Split(t_as,Chr(0))
			Else
				t_ts = t_r.Fields.Item(0).Value
			End If
		End If
		t_r.close() : Set t_r = Nothing
		If Err.number <> 0 Then
			'出错处理
			'Easp.Error.Raise 23 : Err.Clear
		End If
		ReadTable = t_ts
		Err.Clear()
	End Function
	
	'''根据指定条件获取某条纪录中的其他字段的内容
	'ReadTable的别名
	Public Function RT(Byval p_t, Byval p_c, Byval p_g)
		RT = ReadTable(p_t, p_c, p_g)
	End Function
	
	'''调用一个MSSQL存储过程并返回数据
	'p_n:存储过程名
	'p_p:存储过程类型
	Public Function DoSP(Byval p_n, Byval p_p)
		'On Error Resume Next
		Dim t_p, t_t, t_c, t_o, t_i, t_r : t_t = ""
		If Not s_dbType="0" And Not s_dbType="MSSQL" Then
			'存储过程仅支持MSSQL
			'出错处理
			'Easp.Error.Raise 32
			Exit Function
		End If
		t_p = Param(p_n)
		If Has(t_p(1)) Then
			t_t = UCase(Trim(t_p(1)))
			p_n = Trim(t_p(0))
			t_p = ""
		End If
		Set t_c = Server.CreateObject("ADODB.Command")
		With t_c
			.ActiveConnection = s_conn
			.CommandText = p_n
			.CommandType = 4
			.Prepared = true
			.Parameters.append .CreateParameter("return",3,4)
			t_o = "return"
			If Not IsArray(p_p) Then
				If p_p<>"" Then
					p_p = IIF(Instr(p_p,",")>0, p_p = Split(p_p,","), Array(p_p))
				End If
			End If
			If IsArray(p_p) Then
				For t_i = 0 To Ubound(p_p)
					Dim t_pn, t_pv
					If (t_t = "1" Or t_t = "OUT" Or t_t = "3" Or t_t = "ALL") And Instr(p_p(t_i),"@@")=1 Then
						.Parameters.append .CreateParameter(p_p(t_i),200,2,8000)
						t_o = t_o & "," & p_p(t_i)
					Else
						If Instr(p_p(t_i),"@")=1 And Instr(p_p(t_i),":")>2 Then
							t_pn = Left(p_p(t_i),Instr(p_p(t_i),":")-1)
							t_o = t_o & "," & t_pn
							t_pv = Mid(p_p(t_i),Instr(p_p(t_i),":")+1)
							If t_pv = "" Then
								t_pv = NULL
							End If
							.Parameters.append .CreateParameter(t_pn,200,1,8000,t_pv)
						Else
							.Parameters.append .CreateParameter("@param"&(t_i+1),200,1,8000,p_p(t_i))
							t_o = t_o & "," & "@param"&(t_i+1)
						End If
					End If
				Next
			End If
		End With
		t_o = IIF(Instr(t_o,",")>0, Split(t_o,","), Array(t_o))
		If t_t = "1" Or t_t = "OUT" Then
			t_c.Execute : DoSP = t_c
		ElseIf t_t = "2" Or t_t = "RS" Then
			Set DoSP = t_c.Execute
		ElseIf t_t = "3" Or t_t = "ALL" Then
			Dim t_no : Set t_no = Server.CreateObject(C_DicName)
			Set t_r = t_c.Execute : t_r.close
			For t_i = 0 To Ubound(t_o)
				t_no(Trim(t_o(t_i))) = t_c(t_i)
			Next
			t_r.Open : DoSP = Array(t_r,t_no)
			Set t_no = Nothing
		Else
			t_c.Execute : DoSP = t_c(0)
		End If
		Sa.DbQueryTimes = Sa.DbQueryTimes + 1
		Set t_c = Nothing
		If Err.number <> 0 Then
			'出错处理
			'Easp.Error.Raise 24
		End If
		Err.Clear()
	End Function
	
	'''初始化分页数据并得到记录集
	'p_s:type[:pageParam][:pageSize], 分页方式、URL分页GET参数、每页记录数
	'p_c:数组条件/获取记录集的SQL语句/已经存在的记录集(Recordset)对象
	Public Function GetPageRecord(Byval p_s, Byval p_c)
		'On Error Resume Next
		Dim t_t, t_r, t_rs, t_o, t_p, t_s, t_n, t_i,t_rt, t_pp, t_ps
		t_o = Param(Cstr(p_s))
		t_t = t_o(0)
		If Has(t_o(1)) Then
			t_p = Param(t_o(1))
			If Has(t_p(1)) Then
				t_pp = Lcase(t_p(0))
				t_ps = Int(t_p(1))
			Else
				If IsNumeric(t_o(1)) Then
					t_ps = Int(t_o(1))
				Else
					t_pp = Lcase(t_o(1))
				End If
			End If
		Else
			t_pp = "p"
			t_ps = 10
		End If
		'''计算当前页面,如果手动设置了正常页码则直接返回
		If IsNumeric(s_pageIndex)=False Then
			If Request(t_pp)="" Then
				s_pageIndex = 1
			ElseIf Not(IsNumeric(Request(t_pp))) Then
				s_pageIndex = 1
			ElseIf CLng(Trim(Request(t_pp)))<1 Then
				s_pageIndex = 1
			Else
				s_pageIndex = CLng(Trim(Request(t_pp)))
			End If
		Else
			If s_pageIndex<=0 Then
				s_pageIndex = 1
			End If
			s_pageIndex = CLng(s_pageIndex)
		End If
		Select Case Lcase(t_t)
		Case "array","0"
			If IsArray(p_c) Then
				Dim t_tb,t_fi,t_wh
				t_o = Param(p_c(0))
				If Has(t_o(1)) Then
					t_tb = t_o(0) : t_fi = t_o(1)
				Else
					t_tb = p_c(0) : t_fi = "*"
				End If
				If IsArray(p_c(1)) Then
					t_wh = valueToSql_(t_tb,p_c(1),1)
				Else
					t_wh = p_c(1)
				End If
				s_pageRecordCount = Int(ReadTable(t_tb, IIF(IsN(t_wh),"1=1",t_wh), "Count(0)"))
				t_n = s_pageRecordCount / t_ps
				s_pageCount = IIF(t_n=Int(t_n), t_n, Int(t_n)+1)
				s_pageIndex = IIF(s_pageIndex > s_pageCount, s_pageCount, s_pageIndex)
				If s_dbType = "1" or s_dbType = "ACCESS" Then
					Set t_rs = GetRecord(t_tb&":"&t_fi,t_wh,p_c(2))
					t_rs.PageSize = t_ps
					If s_pageRecordCount>0 Then
						t_rs.AbsolutePage = s_pageIndex
					End If
					Set GetPageRecord = t_rs
					Exit Function
				ElseIf s_dbType = "2" or s_dbType = "MYSQL" Then
					t_s = "Select "& t_fi & " From [" & t_tb & "]"
					If Has(t_wh) Then
						t_s = t_s & " Where " & t_wh
					End If
					If Has(p_c(2)) Then
						t_s = t_s & " Order By " & p_c(2)
					End If
					t_s = t_s & " Limit " & t_ps*(s_pageIndex-1) & ", " & t_ps
				Else
					If Ubound(p_c)<>3 Then
						'出错处理
						Errc.Raise(27)
					End If
					t_s = "Select Top " & t_ps & " " & t_fi
					t_s = t_s & " From [" & t_tb & "]"
					If Has(t_wh) Then
						t_s = t_s & " Where " & t_wh
					End If
					If s_pageIndex > 1 Then
						t_s = t_s & " " & IIF(IsN(t_wh), "Where", "And") & " " & p_c(3) & " Not In ("
						t_s = t_s & "Select Top " & t_ps * (s_pageIndex-1) & " " & p_c(3) & " From [" & t_tb & "]"
						If Has(t_wh) Then
							t_s = t_s & " Where " & t_wh
						End If
						If Has(p_c(2)) Then
							t_s = t_s & " Order By " & p_c(2)
						End If
						t_s = t_s & ") "
					End If
					If Has(p_c(2)) Then
						t_s = t_s & " Order By " & p_c(2)
					End If
				End If
				Set GetPageRecord = GetRecordBySQL(t_s)
			Else
				'出错处理
				Errc.Raise(28)
			End If
		Case "sql","1"
			Set t_rs = GetRecordBySQL(p_c)
		Case "rs","2"
			Set t_rs = p_c
		Case Else
			If IsArray(p_c) Then
				If t_t = "" Then
					t_t = s_pageSpName
				End If
				Select Case t_t
				Case "sp_ashapo_pager"
					If Ubound(p_c)<>5 Then
						'出错处理
						Errc.Raise(29)
					End If
					t_r = DoSP("sp_ashapo_pager:3",Array("@TableName:"&p_c(0),"@FieldList:"&p_c(1),"@t_wh:"&p_c(2),"@Order:"&p_c(3),"@PrimaryKey:"&p_c(4),"@SortType:"&p_c(5),"@RecorderCount:0","@pageSize:"&t_ps,"@PageIndex:"&s_pageIndex,"@@RecordCount","@@PageCount"))
				Case Else
					t_rt = Array(False,False)
					For t_i = 0 To Ubound(p_c)
						If LCase(p_c(t_i)) = "@@recordcount" Then
							t_rt(0) = True
						End If
						If LCase(p_c(t_i)) = "@@pagecount" Then
							t_rt(1) = True
						End If
						If t_rt(0) And t_rt(1) Then
							Exit For
						End If
					Next
					If t_rt(0) And t_rt(1) Then
						t_r = DoSP(t_t&":3",p_c)
					Else
						'出错处理
						Errc.Raise(30)
					End If
				End Select
				Set GetPageRecord = t_r(0)
				s_pageRecordCount = Int(t_r(1)("@@RecordCount"))
				s_pageCount = Int(t_r(1)("@@PageCount"))
				s_pageIndex = IIF(s_pageIndex > s_pageCount, s_pageCount, s_pageIndex)
			Else
				'出错处理
				Errc.Raise(31)
			End If
		End Select
		If Instr(",sql,rs,1,2,", "," & t_t & ",")>0 Then
			s_pageRecordCount = t_rs.RecordCount
			t_rs.PageSize = t_ps
			s_pageCount = t_rs.PageCount
			s_pageIndex = IIF(s_pageIndex > s_pageCount, s_pageCount, s_pageIndex)
			If s_pageRecordCount>0 Then
				t_rs.AbsolutePage = s_pageIndex
			End If
			Set GetPageRecord = t_rs
		End If
	End Function

	'''初始化分页数据并得到记录集
	'GetPageRecord的别名
	Public Function GPR(Byval p_s, Byval p_c)
		Set GPR = GetPageRecord(p_s, p_c)
	End Function
	
	'''取得当前分页记录集总页数
	'使用GetPageRecord时有效
	Public Property Get PageCount()
		PageCount = s_pageCount
	End Property

	'''取得当前分页记录集总记录数
	'使用GetPageRecord时有效
	Public Property Get PageRecordCount()
		PageRecordCount = s_pageRecordCount
	End Property
	
	'''手动设置当前页码,分页前如果手动设置页码则生效,未手动设置则按GET形式进行
	'p_i:当前页码数字(置空请使用Null)
	Public Property Let PageIndex(Byval p_i)
		s_pageIndex = p_i
	End Property
	
	'''获取分页记录集当前页码
	Public Property Get PageIndex()
		PageIndex = s_pageIndex
	End Property
End Class
%>